<template>
  <div>
    <template v-if="isDefault">
      <div
        v-if="!imgFile"
        class="upload-default"
        :style="{
          width: width + 'px',
          height: isNaN(ratio) ? width + 'px' : width / ratio + 'px',
        }"
        @click="fileInput?.click()"
      >
        <el-icon class="upload-icon"><UploadFilled /></el-icon>
      </div>
      <div
        v-else
        class="upload-img"
        :style="{
          width: width + 'px',
          height: isNaN(ratio) ? width + 'px' : width / ratio + 'px',
        }"
      >
        <div class="close" @click="removeImage">
          <el-icon class="icon-close"><Close /></el-icon>
        </div>
        <el-image :src="imgFile" style="width: 100%; height: 100%" fit="cover" />
      </div>
    </template>
    <div v-else @click="fileInput?.click()">
      <slot> </slot>
    </div>
    <input type="file" ref="fileInput" accept="image/*" hidden @change="handleFileChange" />
    <ImageCropper v-model="dialogVisible" :ratio="ratio" @confirm="handleCropperImg" :img-url="imgFileCropBefore" />
  </div>
</template>

<script lang="ts" setup>
const props = defineProps({
  isDefault: {
    type: Boolean,
    default: true,
  },
  width: {
    type: Number,
    default: 200,
  },
  ratio: {
    type: Number,
    default: 1,
  },
  url: {
    type: String,
    default: '',
  },
})
// base64图片
const imgFile = ref()
const imgFileCropBefore = ref()
watch(
  () => props.url,
  newVal => {
    if (newVal) {
      imgFile.value = newVal
    }
  },
  { immediate: true }
)
const emit = defineEmits(['confirm'])
// 图片裁剪相关开始
const dialogVisible = ref(false)
// inputRef
const fileInput = ref<HTMLInputElement>()
const handleCropperImg = (val: string) => {
  imgFile.value = val
  emit('confirm', val)
}
// 清空图片
const removeImage = () => {
  imgFile.value = ''
}
// 选择完图片
const handleFileChange = async () => {
  const files = fileInput.value?.files
  if (files && files.length > 0) {
    imgFileCropBefore.value = await convertToBase64(files[0])
    dialogVisible.value = true
  }
  if (fileInput.value) {
    fileInput.value.value = ''
  }
}
// file转base64
const convertToBase64 = (file: File): Promise<string | ArrayBuffer | null> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader()
    const blob = new Blob([file], { type: file.type })
    reader.onload = () => resolve(reader.result)
    reader.onerror = error => reject(error)
    reader.readAsDataURL(blob)
  })
}
</script>

<style scoped lang="scss">
.upload-default {
  font-size: $fontsize12;
  width: 100%;
  height: 100%;
  border-radius: 5px;
  box-sizing: border-box;
  border: 1px dashed #d9d9d9;
  display: grid;
  place-items: center;
  &:hover {
    border-color: #409eff;
  }
  .upload-icon {
    font-size: 48px;
    color: #c0c4cc;
  }
}
.upload-img {
  position: relative;
  .close {
    position: absolute;
    width: 18px;
    height: 18px;
    background-color: rgba(0, 0, 0, 0.7);
    top: -9px;
    // left: 363px;
    right: -9px;
    z-index: 99;
    cursor: pointer;
    // text-align: center;
    // line-height: 18px;
    border-radius: 50%;
    display: grid;
    place-items: center;

    .icon-close {
      color: #fff;
      font-size: 12px;
    }
  }
}
</style>
